package com.file.manage.infrastructure.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.utils.IOUtils;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName：FileUtils
 * @Author：H41
 * @Date：2025/5/23 上午9:50
 * @Desc： 文件工具类
 */
@Slf4j
public class FileUtils {

    public static final String TMP_FILE_PATH = "tmp";
    public static final String FILE_PATH = "upload";

    /**
     * 获取文件后缀名
     */
    public static String getFileSuffix(String fileName) {
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    public static String toFileName(String name) {
        return IdGenerator.identity() + "." + name.substring(name.lastIndexOf(".") + 1);
    }

    public static File tmp2FormalFile(String tmpFilePath, String fileName) throws IOException {
        if (tmpFilePath.contains(TMP_FILE_PATH)) {
            File file = new File(tmpFilePath);
            if (!file.exists()) return null;
            try (FileInputStream fileInputStream = new FileInputStream(file)) {

                File fileRes = downLoad(fileName, fileInputStream);
                // 删除临时文件
                file.delete();
                return fileRes;
            } catch (Exception e) {
                log.error("临时文件转化失败:{}", e.getMessage(), e);
                return null;
            }
        } else {
            log.error("文件不在临时文件夹");
            return null;
        }

    }


    /**
     * 下载文件到临时文件夹
     */

    public static File downLoadTmpFile(String fileName, InputStream inputStream) throws IOException {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        List<String> folderPaths = new ArrayList<>();
        folderPaths.add((format.format(new Date())));
        return downLoadTmpFile(folderPaths, fileName, inputStream);
    }

    public static File downLoadTmpFile(List<String> folderPaths, String fileName, InputStream inputStream) throws IOException {
        List<String> newFolderPaths = new ArrayList<>();
        newFolderPaths.add(TMP_FILE_PATH);
        if (CollUtil.isNotEmpty(folderPaths)) newFolderPaths.addAll(folderPaths);
        return downLoad(newFolderPaths, fileName, inputStream);
    }

    public static File downLoad(String fileName, InputStream inputStream) throws IOException {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        List<String> folderPaths = new ArrayList<>();
        folderPaths.add(FILE_PATH);
        folderPaths.add((format.format(new Date())));
        return downLoad(folderPaths, fileName, inputStream);
    }

    /**
     * 下载文件到本地
     */
    public static File downLoad(List<String> folderPaths, String fileName, InputStream inputStream) throws IOException {
        FileOutputStream fileOut = null;
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        try {
            // 组合完整路径
            StringBuilder stringBuffer = new StringBuilder();
            if (CollUtil.isNotEmpty(folderPaths)) {
                for (String folderPath : folderPaths) {
                    stringBuffer.append(folderPath);
                    File directory = new File(stringBuffer.toString());
                    if (!directory.exists()) {
                        directory.mkdirs(); // 自动创建文件夹（包括父目录）
                    }
                    stringBuffer.append("/");
                }
            }
            stringBuffer.append(fileName);
            File file = new File(stringBuffer.toString());
            if (!file.exists()) {
                //如果文件不存在，则创建新的的文件夹
                file.createNewFile();
            }
            fileOut = new FileOutputStream(file);
            bos = new BufferedOutputStream(fileOut);
            bis = new BufferedInputStream(inputStream);
            byte[] buf = new byte[4096];
            int length = bis.read(buf);
            //保存文件
            while (length != -1) {
                bos.write(buf, 0, length);
                length = bis.read(buf);
            }
            return file;
        } catch (Exception e) {
            log.error("文件下载失败:{}", e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            //释放资源
            if (bos != null) bos.close();
            if (bis != null) bis.close();
            if (fileOut != null) fileOut.close();
        }
    }

    public static void deleteFile(String fileUrl) {
        if (FileUtil.exist(fileUrl)) {
            FileUtil.del(fileUrl);
        }
    }


    /**
     * 从 InputStream 解压 ZIP 文件到目标目录
     *
     * @param zipInputStream ZIP 文件的输入流
     * @param targetDir      解压到的目标目录
     * @throws IOException 如果解压失败
     */
    public static void unzip(InputStream zipInputStream, String targetDir) throws IOException {
        Path targetPath = Paths.get(targetDir);
        if (!Files.exists(targetPath)) {
            Files.createDirectories(targetPath);
        }

        try (ZipArchiveInputStream zipIn = new ZipArchiveInputStream(zipInputStream)) {
            ZipArchiveEntry entry;
            while ((entry = zipIn.getNextZipEntry()) != null) {
                Path entryPath = targetPath.resolve(entry.getName());

                if (entry.isDirectory()) {
                    Files.createDirectories(entryPath); // 创建目录
                } else {
                    // 确保父目录存在
                    Files.createDirectories(entryPath.getParent());

                    // 写入文件
                    try (OutputStream out = Files.newOutputStream(entryPath)) {
                        IOUtils.copy(zipIn, out);
                    }
                }
            }
        }
    }
}
